<template>
  <div class="filter-setting">
    <div id="setting-resize" class="resize-line" />
    <div class="setting-header">过滤设置</div>

    <!-- 设置内容-->
    <div
      id="setting-content"
      class="setting-content"
      :style="`height:${
        getFilterSettingType(activeFilter) !== 'close' ? settingHeight : 0
      }px`"
    >
      <!--选项过滤器-->
      <div
        v-if="getFilterSettingType(activeFilter) === 'checkbox'"
        class="setting-row"
      >
        <div class="form-name">
          {{ activeFilter.name }}{{ activeFilter.data.attr }}：
        </div>
        <a-select
          v-model="selectedOptions"
          mode="multiple"
          class="params-body"
          :max-tag-count="maxTagCount"
          :placeholder="activeFilter.data.setParams[0].tips"
          show-arrow
          @change="handleSelectOptionsChange"
        >
          <a-select-option v-for="option in options" :key="option"
            >{{ option }}
          </a-select-option>
        </a-select>
      </div>
      <!--范围过滤器-->
      <div
        v-else-if="getFilterSettingType(activeFilter) === 'slider'"
        class="setting-row"
      >
        <div class="form-label">{{ activeFilter.data.attr }}范围</div>
        <div class="form-name">{{ selectedRange[0] }}</div>
        <a-slider
          v-model="selectedRange"
          :min="range[0]"
          :max="range[1]"
          :step="step"
          range
          class="params-body"
          @afterChange="handleRangeChange"
        />
        <div class="form-name">{{ selectedRange[1] }}</div>
      </div>
      <!--内部边和外部边-->
      <div
        v-else-if="
          getFilterSettingType(activeFilter) === 'innerOrOuterEdegeType'
        "
        class="setting-row"
      >
        <div class="form-name">
          {{ activeFilter.data.attr }} {{ activeFilter.name }}：
        </div>
        <a-select
          v-model="selectedEdgeOption"
          mode="multiple"
          show-arrow
          class="params-body"
          :max-tag-count="maxTagCount"
          :placeholder="activeFilter.data.setParams[0].tips"
          @change="handleEdgeSelectChange"
        >
          <a-select-option
            v-for="option in edgeOptions"
            :key="`${option.value}(${option.proportion})`"
            >{{ `${option.value}(${option.proportion})` }}
          </a-select-option>
        </a-select>
      </div>
      <!--属性等于-->
      <div
        v-else-if="getFilterSettingType(activeFilter) === 'string'"
        class="setting-row"
      >
        <div class="form-label">{{ activeFilter.data.attr }} 等于:</div>
        <a-input
          v-model="inputValue"
          v-focus
          class="params-body"
          @keyup.enter.native="$event.target.blur"
          @blur="handleEqualChange"
        />
      </div>
      <!--K核心-->
      <div
        v-else-if="getFilterSettingType(activeFilter) === 'number'"
        class="setting-row"
      >
        <div class="form-label">保留度值:</div>
        <a-input-number
          v-model="inputValue"
          v-focus
          class="params-body"
          @keyup.enter.native="$event.target.blur"
          @blur="handleKKernalChange"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import GraphAnalysis from '@/store/modules/graphanalysis'
import {
  Filter,
  FilterData,
} from '@/components/graph-analysis/right-drawer/data-filter/data-filter'

@Component({
  components: {},
})
export default class FilterSetting extends Vue {
  // ----------定义高度------------
  private settingHeight = 80 // 设置内容高度
  private settingMaxHeight = 350 // 设置最大高度
  private settingMinHeight = 80 // 设置最小高度

  // ------------定义各类型过滤器的设置信息----------------
  // 所有范围类型的属性的step
  private step = 1
  // 多选框选项
  private options: string[] = []
  private selectedOptions: string[] = []
  // 范围拖动条
  private range: number[] = []
  private selectedRange: number[] = []
  // 输入框的值
  private inputValue: string | number = ''
  // 内部边和外部边
  private edgeOptions: any[] = []
  private selectedEdgeOption: string[] = []
  // 下拉框最多能显示几个，如果选了超过限制的个数，就使用...
  private maxTagCount = 3

  public mounted() {
    this.initViewEvent()
  }

  // 初始化resize事件
  public initViewEvent() {
    const resizeBar = document.querySelector('#setting-resize') as any

    // 鼠标按下事件
    const mouseDownEvent = ($event: any) => {
      const initContentHeight = this.settingHeight
      const startY = $event.clientY
      const mouseMoveEvent: any = (event: any) => {
        if (this.getFilterSettingType(this.activeFilter) === 'close') {
          return
        }
        const endY = event.clientY
        const moveLength = endY - startY
        let contentHeight = initContentHeight - moveLength
        if (contentHeight > this.settingMaxHeight) {
          contentHeight = this.settingMaxHeight
        } else if (contentHeight < this.settingMinHeight) {
          contentHeight = this.settingMinHeight
        }
        this.settingHeight = contentHeight
        this.$forceUpdate()
      }
      document.addEventListener('mousemove', mouseMoveEvent)
      const mouseUpEvent: any = () => {
        document.removeEventListener('mousemove', mouseMoveEvent)
        document.removeEventListener('mouseup', mouseUpEvent)
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        resizeBar.releaseCapture && resizeBar.releaseCapture()
      }
      document.addEventListener('mouseup', mouseUpEvent)
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      resizeBar.setCapture && resizeBar.setCapture()
      return false
    }
    resizeBar.addEventListener('mousedown', mouseDownEvent)
    this.$once('hook:beforeDestroy', () => {
      resizeBar.removeEventListener('mousedown', mouseDownEvent)
    })
  }

  public beforeDestroy() {}

  // 修改过滤过滤器设置
  public async updateFilter(value: any) {
    // 如果未选中过滤器，则直接返回
    if (this.activeFilter === null) {
      return
    }

    // 修改过滤器
    const setParameters: any = {
      ...this.activeFilter.data.setParams[0],
      value,
    }
    const data: FilterData = {
      ...this.activeFilter.data,
      setParams: [setParameters],
    }
    const filter: any = {
      ...this.activeFilter,
      data,
    }

    const response = await GraphAnalysis.updateGraphFilter({
      ...filter,
    })
    // 重新设置被选中的filter
    if (response.success) {
      GraphAnalysis.setActiveFilter(filter)
    }
  }

  // 获取过滤器设置类型
  public getFilterSettingType(filter: Filter | null) {
    // 判断当前选中过滤器的类型
    let matchedKey: string | undefined = 'close'

    if (filter !== null) {
      const { data, subType } = filter
      if (data?.setParams[0]) {
        const { type } = data?.setParams[0]
        if (type === 'checkbox') {
          if ([12, 13].includes(subType)) {
            return 'innerOrOuterEdegeType'
          }
        }
        matchedKey = type
      }
    }

    // 如果是不需要配置的过滤器
    return matchedKey || 'close'
  }

  // 监听选中过滤器的修改
  @Watch('activeFilter')
  public async handleFilterChange() {
    // 如果是取消选中，则直接返回
    if (this.activeFilter === null) {
      return
    }

    // 如果选中的是选项过滤器
    if (this.getFilterSettingType(this.activeFilter) === 'checkbox') {
      this.options = this.activeFilter.data.setParams[0].default as string[]
      this.selectedOptions = this.activeFilter.data.setParams[0]
        .value as string[]
    }
    // 如果选中的是边权重范围
    else if (this.getFilterSettingType(this.activeFilter) === 'slider') {
      const value = this.activeFilter.data.setParams[0].value as number[]
      const { min, max, step } = this.activeFilter.data.setParams[0]
      this.range = [min, max]
      this.selectedRange = value
      this.step = step
    }
    // 如果选中的是属性等于
    else if (this.getFilterSettingType(this.activeFilter) === 'string') {
      const value = this.activeFilter.data.setParams[0].value as string
      this.inputValue = value
    }
    // 如果选中的是K核心
    else if (this.getFilterSettingType(this.activeFilter) === 'number') {
      const value = this.activeFilter.data.setParams[0].value as number
      this.inputValue = value
    }
    // 如果选中的是内部边
    else if (
      this.getFilterSettingType(this.activeFilter) === 'innerOrOuterEdegeType'
    ) {
      this.edgeOptions = this.activeFilter.data.setParams[0].default as any[]
      this.selectedEdgeOption = (this.activeFilter.data.setParams[0]
        .value as any[]).map((v) => {
        return `${v.value}(${v.proportion})`
      })
    }
  }

  // 获取当前选中过滤器名字
  public get activeFilter() {
    return GraphAnalysis.activeFilter
  }

  // 项目id
  public get projectId() {
    return GraphAnalysis.projectId
  }

  // 图id
  public get graphId() {
    return GraphAnalysis.activeTabId
  }

  // --------------处理设置改变-------------------
  // 修改多选框内容
  public handleSelectOptionsChange(value: string[]) {
    this.selectedOptions = value
    this.updateFilter(value)
  }

  // 修改范围值
  public handleRangeChange() {
    this.updateFilter(this.selectedRange)
  }

  // 修改属性内部边和外部边
  public handleEdgeSelectChange(value: any[]) {
    this.selectedEdgeOption = value
    this.updateFilter(
      this.selectedEdgeOption.map((edge) => {
        const temporary: string = edge.replace(')', '')
        const splitIndex = temporary.indexOf('(')
        return {
          value: temporary.slice(0, splitIndex),
          proportion: Number.parseFloat(temporary.slice(splitIndex + 1)),
        }
      })
    )
  }

  // 修改属性等于
  public handleEqualChange() {
    this.updateFilter(this.inputValue)
  }

  // 修改K核心的值
  public handleKKernalChange() {
    this.updateFilter(this.inputValue)
  }
}
</script>

<style scoped lang="less">
.filter-setting {
  background: #f9f9fc;
  margin-bottom: 38px;
  margin-top: auto;
  width: 100%;

  .resize-line {
    border-bottom: 1px #e9e9e9 solid;
    cursor: row-resize;
    height: 5px;
    width: 100%;
  }

  .setting-header {
    color: #5d637e;
    font-size: 14px;
    font-weight: 600;
    height: 38px;
    letter-spacing: 1px;
    line-height: 38px;
    padding-left: 15px;
    user-select: none;
    width: 100%;
  }

  .setting-content {
    padding-left: 15px;
    width: 100%;

    .setting-row {
      align-items: center;
      display: flex;
      padding: 8px 10px;
      width: 100%;

      .form-label,
      .form-name {
        user-select: none;
      }

      .form-name {
        text-align: center;
        width: 50px;
      }

      .params-body {
        flex: 1;
        margin: 0 5px;
      }
    }
  }
}
</style>
